package club.xiaojiawei.linkedlist;

/**
 * @author 肖嘉威
 * @version 1.0
 * @date 2022/4/21 23:46
 * @question 707.设计链表
 * @description 设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性：val 和 next。val 是当前节点的值，next 是指向下一个节点的指针/引用。如果要使用双向链表，则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。
 * 在链表类中实现这些功能：
 * get(index)：获取链表中第 index 个节点的值。如果索引无效，则返回-1。
 * addAtHead(val)：在链表的第一个元素之前添加一个值为 val 的节点。插入后，新节点将成为链表的第一个节点。
 * addAtTail(val)：将值为 val 的节点追加到链表的最后一个元素。
 * addAtIndex(index,val)：在链表中的第 index 个节点之前添加值为 val  的节点。如果 index 等于链表的长度，则该节点将附加到链表的末尾。如果 index 大于链表长度，则不会插入节点。如果index小于0，则在头部插入节点。
 * deleteAtIndex(index)：如果索引 index 有效，则删除链表中的第 index 个节点。
 */
public class MyLinkedList707 {

    private Integer val;

    private MyLinkedList707 next;

    public MyLinkedList707() {

    }

    public MyLinkedList707 getNext() {
        return next;
    }

    public void setNext(MyLinkedList707 next) {
        this.next = next;
    }

    public MyLinkedList707(int val) {
        this.val = val;
    }

    public MyLinkedList707(int val, MyLinkedList707 next) {
        this.val = val;
        this.next = next;
    }

    public int get(int index) {
        if (index < 0 || this.val == null){
            return -1;
        }
        MyLinkedList707 temp = this;
        int count = 0;
        while (index != count++){
            if (temp.next == null){
                return -1;
            }
            temp = temp.next;
        }
        return temp.val;
    }

    public void addAtHead(int val) {
        if (this.val == null){
            this.val = val;
            return;
        }
        MyLinkedList707 linkedList = new MyLinkedList707(this.val, this.next);
        this.val = val;
        this.next = linkedList;
    }

    public void addAtTail(int val) {
        if (this.val == null){
            this.val = val;
            return;
        }
        MyLinkedList707 temp = this;
        while (temp.next != null){
            temp = temp.next;
        }
        temp.next = new MyLinkedList707(val);
    }

    public void addAtIndex(int index, int val) {
        if (index <= 0){
            addAtHead(val);
        }
        int count = 1;
        MyLinkedList707 temp = this;
        while (true){
            if (temp.next == null){
                if (index == count){
                    if (this.val != null || index != 1){
                        addAtTail(val);
                    }
                }
                return;
            }else if (count++ == index){
                temp.next = new MyLinkedList707(val,temp.next);
                return;
            }else {
                temp = temp.next;
            }
        }
    }

    public void deleteAtIndex(int index) {
        if (index < 0){
            return;
        }else if (index == 0){
            if (this.next != null){
                this.val = this.next.val;
                this.next = this.next.next;
            }else {
                this.val = null;
            }
            return;
        }
        int count = 1;
        MyLinkedList707 temp = this;
        while (temp.next != null){
            if (index == count++){
                temp.next = temp.next.next;
                return;
            }else {
                temp = temp.next;
            }
        }
    }
}
class Test{
    public static void main(String[] args) {
        MyLinkedList707 myLinkedList707 = new MyLinkedList707();
        myLinkedList707.addAtIndex(1, 0);
//        myLinkedList.addAtIndex(1, 2);
        System.out.println(myLinkedList707.get(0));
//        myLinkedList.addAtHead(1);
//        myLinkedList.addAtTail(3);
//        myLinkedList.addAtIndex(1, 2);
//        System.out.println(myLinkedList.get(1));
//        myLinkedList.deleteAtIndex(1);
//        System.out.println(myLinkedList.get(1));
//        System.out.println(myLinkedList.get(3));
//        myLinkedList.deleteAtIndex(3);
//        myLinkedList.deleteAtIndex(0);
//        System.out.println(myLinkedList.get(0));
//        myLinkedList.deleteAtIndex(0);
//        System.out.println(myLinkedList.get(0));
    }
}
